﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Collections;
using System.Configuration;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.UI;

namespace LsoaClass
{
    /// <summary>
    /// 封装DataSet，其操作类似于SqlDataReader
    /// </summary>
    public class LsDataSet
    {
        private int index = - 1;
        private DataSet dataSet = new DataSet();

        public LsDataSet()
        {
        }

        public LsDataSet(DataSet ds)
        {
            if (ds != null)
                dataSet = ds;
        }

        public LsDataSet(string xml)
        {
            readXML(xml);
        }

        public DataSet DataSet
        {
            get { return dataSet; }
            set { dataSet = value; }
        }

        public DataTable Table
        {
            get { return dataSet.Tables[0]; }
        }

        public void first()
        {
            index = -1;
        }

        public bool read()
        {
            index++;
            if (dataSet.Tables[0].Rows.Count > index)
                return true;
            else
                return false;
        }

        public void clear()
        {
            dataSet.Dispose();
            dataSet = new DataSet();
            index = -1;
        }

        public object this[string item]
        {
            get { return dataSet.Tables[0].Rows[index][item]; }
        }

        public object this[int item]
        {
            get { return dataSet.Tables[0].Rows[index][item]; }
        }

        public string toXML()
        {
            System.Text.StringBuilder strbuilder = new System.Text.StringBuilder();
            StringWriter writer = new StringWriter(strbuilder);
            dataSet.WriteXml(writer, XmlWriteMode.WriteSchema);
            return strbuilder.ToString();
        }

        public string toXML(int tableIndex)
        {
            System.Text.StringBuilder strbuilder = new System.Text.StringBuilder();
            StringWriter writer = new StringWriter(strbuilder);
            dataSet.Tables[tableIndex].WriteXml(writer, XmlWriteMode.WriteSchema);
            return strbuilder.ToString();
        }

        public string toXML(string fields)
        {
            if (fields == "")
            {
                return toXML();
            }
            else
            {
                System.Text.StringBuilder strbuilder = new System.Text.StringBuilder();
                StringWriter writer = new StringWriter(strbuilder);
                DataSet ds = dataSet;
                string[] fieldname = fields.Split(',');
                ArrayList list = new ArrayList();
                for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
                {
                    list.Add(j);
                }
                for (int i = 0; i < fieldname.Length; i++)
                {
                    list.Remove(ds.Tables[0].Columns.IndexOf(fieldname[i]));
                }
                for (int i = list.Count - 1; i >= 0; i--)
                {
                    ds.Tables[0].Columns.RemoveAt(int.Parse(list[i].ToString()));
                }
                ds.WriteXml(writer, XmlWriteMode.WriteSchema);
                return strbuilder.ToString();
            }
        }

        public void readXML(string xml)
        {
            index = -1;
            StringReader reader = new StringReader(xml);
            dataSet.ReadXml(reader, XmlReadMode.Auto);
        }
    }

    /// <summary>
    /// 基本的数据库操作类
    /// </summary>
    public class DBClass
    {
        private SqlConnection SqlConn;
        public int CommandTimeout = 30;  //执行命令的超时时间（只对getPageDataSet与getPageLsDataSet有效）

        public DBClass()
        {
            open();
        }

        public DBClass(string dbName)
        {
            open(dbName);
        }

        private static string getDBConnStr()
        {
            return getDBConnStr(ConfigurationManager.AppSettings["dbname"]);
        }

        private static string getDBConnStr(string dbName)
        {
            string ConnStr, ServerIP, UserName, Password;
            ServerIP = ConfigurationManager.AppSettings["serverip"];
            UserName = ConfigurationManager.AppSettings["username"];
            Password = ConfigurationManager.AppSettings["password"];
            ConnStr = "server=" + ServerIP + ";uid=" + UserName + ";pwd=" + Password + ";database=" + dbName;
            return ConnStr;
        }

        public void open()
        {
            if (SqlConn == null)
            {
                SqlConn = new SqlConnection();
                SqlConn.ConnectionString = getDBConnStr();
                SqlConn.Open();
            }
            else if (SqlConn.State == ConnectionState.Closed)
                SqlConn.Open();
        }

        public void open(string dbName)
        {
            if (SqlConn == null)
            {
                SqlConn = new SqlConnection();
                SqlConn.ConnectionString = getDBConnStr(dbName);
                SqlConn.Open();
            }
            else if (SqlConn.State == ConnectionState.Closed)
                SqlConn.Open();
        }

        public void close()
        {
            if (SqlConn != null)
                SqlConn.Close();
        }

        public SqlCommand getSqlCommand(string sql)
        {
            SqlCommand SqlCmd = new SqlCommand(sql, SqlConn);
            return SqlCmd;
        }

        public bool executeSqlCommand(string sql)
        {
            SqlCommand SqlCmd = new SqlCommand(sql, SqlConn);
            try
            {
                SqlCmd.ExecuteNonQuery();
                return true;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                SqlCmd.Dispose();
            }
        }

        public LsDataSet getLsDataSetBySql(string sql)
        {
            return new LsDataSet(getDataSetBySql(sql));
        }

        public LsDataSet getLsDataSetBySqlCommand(SqlCommand sqlCmd)
        {
            return new LsDataSet(getDataSetBySqlCommand(sqlCmd));
        }

        /// <summary>
        /// 获取分页后的LsDataSet
        /// </summary>
        /// <param name="pageSize">每页的记录数</param>
        /// <param name="currentPage">当前页码</param>
        /// <param name="sqlText">SQL语句</param>
        /// <param name="recordCount">总记录数</param>
        /// <param name="pageCount">总页数</param>
        /// <returns></returns>
        public LsDataSet getPageLsDataSet(int pageSize, int currentPage, string sqlText, out int recordCount, out int pageCount)
        {
            return new LsDataSet(getPageDataSet(pageSize, currentPage, sqlText, out recordCount, out pageCount));
        }

        public DataSet getDataSetBySql(string sql)
        {
            SqlDataAdapter da = new SqlDataAdapter(sql, SqlConn);
            DataSet ds = new DataSet();
            da.Fill(ds);
            da.Dispose();
            return ds;
        }

        public DataSet getDataSetBySqlCommand(SqlCommand sqlCmd)
        {
            SqlDataAdapter da = new SqlDataAdapter(sqlCmd);
            DataSet ds = new DataSet();
            da.Fill(ds);
            da.Dispose();
            return ds;
        }

        /// <summary>
        /// 获取分页后的DataSet
        /// </summary>
        /// <param name="pageSize">每页的记录数</param>
        /// <param name="currentPage">当前页码</param>
        /// <param name="sqlText">SQL语句</param>
        /// <param name="recordCount">总记录数</param>
        /// <param name="pageCount">总页数</param>
        /// <returns></returns>
        public DataSet getPageDataSet(int pageSize, int currentPage, string sqlText, out int recordCount, out int pageCount)
        {
            DataSet refds = new DataSet();
            using (SqlCommand sqlCommand = new SqlCommand())
            {
                sqlCommand.Connection = SqlConn;
                sqlCommand.CommandTimeout = CommandTimeout;
                sqlCommand.CommandText = "set nocount on " +
                    "declare @P1 int " +
                    "declare @rowcount int " +
                    "declare @scrollopt int " +
                    "declare @ccopt int " +
                    "exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output " +
                    "set @pagecount= ceiling(1.0*@rowcount/@pagesize) " +
                    "set @recordcount= @rowcount " +
                    "set @currentpage=(@currentpage-1)*@pagesize+1 " +
                    "exec sp_cursorfetch @P1,16,@currentpage,@pagesize " +
                    "exec sp_cursorclose @P1 " +
                    "set nocount off";
                sqlCommand.Parameters.Add("@sqlstr", SqlDbType.NText);
                sqlCommand.Parameters.Add("@currentpage", SqlDbType.Int);
                sqlCommand.Parameters.Add("@pagesize", SqlDbType.Int);
                sqlCommand.Parameters["@sqlstr"].Value = sqlText;
                sqlCommand.Parameters["@currentpage"].Value = currentPage;
                sqlCommand.Parameters["@pagesize"].Value = pageSize;
                sqlCommand.Parameters.Add("@PageCount", SqlDbType.Int);
                sqlCommand.Parameters["@PageCount"].Direction = ParameterDirection.Output;
                sqlCommand.Parameters.Add("@RecordCount", SqlDbType.Int);
                sqlCommand.Parameters["@RecordCount"].Direction = ParameterDirection.Output;
                using (DataSet ds = new DataSet())
                {
                    using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand))
                    {
                        sqlDataAdapter.Fill(ds);
                    }
                    refds.Tables.Add(ds.Tables[1].Copy());
                }
                pageCount = (int)sqlCommand.Parameters["@PageCount"].Value;
                recordCount = (int)sqlCommand.Parameters["@RecordCount"].Value;
            }

            return refds;
        }

        /// <summary>
        /// 获取SqlDataReader，用完后一定要调用Close()关闭DataReader。
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public SqlDataReader getDataReaderBySql(string sql)
        {
            SqlCommand SqlCmd = new SqlCommand(sql, SqlConn);
            return SqlCmd.ExecuteReader(CommandBehavior.CloseConnection);
        }
    }

    /// <summary>
    /// 将返回代码和提示信息组合成字符串
    /// </summary>
    public class UAPCallResult
    {
        private int _code = 0;
        private string _msg = "";
        private string _retstr = "";

        public UAPCallResult()
        {
            _retstr = "0|";
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="retStr">输入结果串Code+char(18)+Msg</param>
        public UAPCallResult(string retStr)
        {
            RetStr = retStr;
        }

        /// <summary>
        /// 返回结果代码
        /// </summary>
        public int Code
        {
            get { return _code; }
            set
            {
                _code = value;
                _retstr = _code.ToString() + "|" + _msg;
            }
        }

        /// <summary>
        /// 返回提示信息
        /// </summary>
        public string Msg
        {
            get { return _msg; }
            set
            {
                _msg = value;
                _retstr = _code.ToString() + "|" + _msg;
            }
        }

        /// <summary>
        /// 返回结果组合串Code+"|"+Msg
        /// </summary>
        public string RetStr
        {
            get { return _retstr; }
            set
            {
                if (value.IndexOf("|") > 0)
                {
                    try
                    {
                        _code = Int32.Parse(value.Substring(0, value.IndexOf("|")));
                        _msg = value.Substring(value.IndexOf("|") + 1);
                        _retstr = _code.ToString() + "|" + _msg;
                    }
                    catch { }
                }
            }
        }
    }

    /// <summary>
    /// 统一的验证结构
    /// </summary>
    public class SessionKey
    {
        private string _sessionStr = "";
        private string _sessionID = "";
        private string _operatorID = "";
        private string _systemID = "";

        public SessionKey()
        {
        }

        public SessionKey(string sessionStr)
        {
            SessionStr = sessionStr;
        }

        public string SessionID
        {
            get { return _sessionID; }
        }

        public string OperatorID
        {
            get { return _operatorID; }
        }

        public string SystemID
        {
            get { return _systemID; }
        }

        public string SessionStr
        {
            get
            { return _sessionStr; }
            set
            {
                value = CommonFunc.desDecrypt(value, CommonFunc.EncryptKey);
                string[] tmp = value.Split('|');
                if (tmp.Length >= 3)
                {
                    _sessionID = tmp[0];
                    _operatorID = tmp[1];
                    _systemID = tmp[2];
                }
            }
        }

        public static string getSessionID(string sessionStr)
        {
            sessionStr = CommonFunc.desDecrypt(sessionStr, CommonFunc.EncryptKey);
            string[] tmp = sessionStr.Split('|');
            if (tmp.Length >= 3)
                return tmp[0];
            else
                return "";
        }

        public static string getOperatorID(string sessionStr)
        {
            sessionStr = CommonFunc.desDecrypt(sessionStr, CommonFunc.EncryptKey);
            string[] tmp = sessionStr.Split('|');
            if (tmp.Length >= 3)
                return tmp[1];
            else
                return "";
        }

        public static string getSystemID(string sessionStr)
        {
            sessionStr = CommonFunc.desDecrypt(sessionStr, CommonFunc.EncryptKey);
            string[] tmp = sessionStr.Split('|');
            if (tmp.Length >= 3)
                return tmp[2];
            else
                return "";
        }
    }

    /// <summary>
    /// 数据库基础类
    /// </summary>
    public class LsDBClass
    {
        /// <summary>
        /// 内置统一返回UAPCallResult型的结果变量funResult
        /// </summary>
        public static UAPCallResult funResult = new UAPCallResult();
    }

    /// <summary>
    /// 页面基础类
    /// </summary>
    public class LsPage : System.Web.UI.Page, ICallbackEventHandler
    {
        /// <summary>
        /// Session验证字符串
        /// </summary>
        public string sessionStr;

        /// <summary>
        /// 操作员帐号
        /// </summary>
        public string operatorID;

        /// <summary>
        /// 操作员名称
        /// </summary>
        public string operatorName;

        /// <summary>
        /// 系统帐号
        /// </summary>
        public string systemID;

        /// <summary>
        /// 机构编号
        /// </summary>
        public int branchNo;

        /// <summary>
        /// 机构编号
        /// </summary>
        public string deptNo = "";

        /// <summary>
        /// 内置统一返回UAPCallResult型的结果变量result
        /// </summary>
        public UAPCallResult result = new UAPCallResult();

        public void checkSession(Page webPage)
        {
            webPage.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData1", "context");
            webPage.RegisterClientScriptBlock("cookieBy", @"
            <script language=javascript>
                var LsClientCookieReadString='';
                function LsJsGetCookieByNet(extraStr)
                { 
                    arg = 'ServerMethod1|'+extraStr;
                    WebForm_DoCallback('__Page',arg,ReceiveServerData1,'context',null,true); //外面JS用这个就可以实现无刷新页面，其中arg就是对应server的动态调用信息。
                }
                function ReceiveServerData1(result, context) 
                {
                    LsClientCookieReadString=result;
                    var str=result.split('|')
                    LsCustiomFuntion(str[0],str[1]);//异步方式下的，外部处理接口。
                }        
            </script>");
            //检查浏览器版本号，如果IE8以上的就强制使用兼容模式
            HttpBrowserCapabilities bc = HttpContext.Current.Request.Browser;
            if (bc.MajorVersion >= 8)
            {
                webPage.Response.AppendHeader("X-UA-Compatible", "IE=EmulateIE7");
            }

            string httpHost = "http://" + webPage.Request.ServerVariables["Http_Host"].ToString() + webPage.Request.ApplicationPath;
            if (httpHost.Substring(httpHost.Length - 1) != "/")
            {
                httpHost += "/";
            }

            webPage.Response.Expires = -1;
            webPage.Response.ExpiresAbsolute = DateTime.Parse("1900-01-01");
            webPage.Response.CacheControl = "no-cache";
            if (webPage.Request.Cookies["sessionStr"] == null)
            {
                webPage.Response.Write("<script>alert('与服务器的会话无效,请重新登陆！');window.location='" + httpHost + "default.aspx?" + webPage.Request.Url.ToString() + "';</script>");
                webPage.Response.End();
            }
            else
            {
                sessionStr = Server.UrlDecode(webPage.Request.Cookies["sessionStr"].Value);
                operatorID = Server.UrlDecode(webPage.Request.Cookies["OperatorID"].Value);
                operatorName = Server.UrlDecode(webPage.Request.Cookies["OperatorName"].Value);
                systemID = Server.UrlDecode(webPage.Request.Cookies["systemID"].Value);
                branchNo = int.Parse(Server.UrlDecode(webPage.Request.Cookies["branchNo"].Value));
                if (webPage.Request.Cookies["deptNo"] != null)
                    deptNo = Server.UrlDecode(webPage.Request.Cookies["deptNo"].Value);

                UAPCallResult ret = new UAPCallResult();
                ret.RetStr = SystemMaintain.UserClass.checkSession(sessionStr);
                if (ret.Code != 0)
                {
                    webPage.Response.Write("<script>alert('登陆超时,请重新登陆！');window.location='" + httpHost + "default.aspx?" + webPage.Request.Url.ToString() + "';</script>");
                    webPage.Response.End();
                }
            }
        }

        #region ICallbackEventHandler 成员
        string serverReturn = "";
        string ICallbackEventHandler.GetCallbackResult()
        {
            string[] parts = serverReturn.Split('|');
            //根据传递的方法名进行调用，并传递相应的参数，目前只支持一个参数
            //return (string)GetType().GetMethod(parts[0]).Invoke(this, new object[] { parts[1] });
            return parts[1] + "|" + sessionStr;
            Response.End();
        }

        void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
        {
            serverReturn = eventArgument;
        }
        #endregion
    }

    /// <summary>
    /// 常用类方法的集合
    /// </summary>
    public class CommonFunc
    {
        public static string EncryptKey = "Lees@2012.com";  //加密的密钥

        /// <summary>
        /// 采用DES加密字符串
        /// </summary>
        /// <param name="inputStr">明文字符串</param>
        /// <param name="keyStr">密钥</param>
        /// <returns>加密串</returns>
        public static string desEncrypt(string inputStr, string keyStr)
        {
            //处理密钥必须为8位的问题
            keyStr = keyStr + "lkjhgfdsa";
            keyStr = keyStr.Substring(0, 8);
            byte[] byKey = null;
            byte[] IV =   { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            try
            {
                byKey = System.Text.Encoding.UTF8.GetBytes(keyStr);
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                byte[] inputByteArray = Encoding.UTF8.GetBytes(inputStr);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                return strToHexstr(Convert.ToBase64String(ms.ToArray()));
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 采用DES解密字符串
        /// </summary>
        /// <param name="inputStr">已加密的字符串</param>
        /// <param name="keyStr">密钥</param>
        /// <returns>解密后的明文</returns>
        public static string desDecrypt(string inputStr, string keyStr)
        {
            inputStr = hexstrToStr(inputStr);
            //处理密钥必须为8位的问题        
            keyStr = keyStr + "lkjhgfdsa";
            keyStr = keyStr.Substring(0, 8);
            byte[] byKey = null;
            byte[] IV =   { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            byte[] inputByteArray = new Byte[inputStr.Length];
            try
            {
                byKey = System.Text.Encoding.UTF8.GetBytes(keyStr);
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                inputByteArray = Convert.FromBase64String(inputStr);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                System.Text.Encoding encoding = new System.Text.UTF8Encoding();
                return encoding.GetString(ms.ToArray());
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        //字符串转十六进制串
        private static string strToHexstr(string input)
        {
            int x, high, low;
            string ret = "";
            for (int i = 0; i < input.Length; i++)
            {
                x = (int)input[i];
                high = x / 16;
                low = x - high * 16;
                ret += decToHex(high) + decToHex(low);
            }
            return ret;
        }

        //十六进制串转字符串
        private static string hexstrToStr(string input)
        {
            string ret, tmp, high, low;
            int a;
            char c;
            tmp = input;
            ret = "";
            while (tmp.Length > 0)
            {
                high = tmp[0].ToString();
                low = tmp[1].ToString();
                a = hexToDec(high) * 16 + hexToDec(low);
                c = (char)a;
                ret += c;
                tmp = tmp.Substring(2, tmp.Length - 2);
            }
            return ret;
        }

        //十六进制转十进制
        private static int hexToDec(string x)
        {
            int ret;
            switch (x)
            {
                case "A":
                    ret = 10;
                    break;
                case "B":
                    ret = 11;
                    break;
                case "C":
                    ret = 12;
                    break;
                case "D":
                    ret = 13;
                    break;
                case "E":
                    ret = 14;
                    break;
                case "F":
                    ret = 15;
                    break;
                default:
                    ret = int.Parse(x);
                    break;
            }
            return ret;
        }

        //十进制转十六进制
        private static string decToHex(int x)
        {
            string ret;
            switch (x)
            {
                case 10:
                    ret = "A";
                    break;
                case 11:
                    ret = "B";
                    break;
                case 12:
                    ret = "C";
                    break;
                case 13:
                    ret = "D";
                    break;
                case 14:
                    ret = "E";
                    break;
                case 15:
                    ret = "F";
                    break;
                default:
                    ret = x.ToString();
                    break;
            }
            return ret;
        }

        //SHA1加密
        public static string sha1Encrypt(string sourceStr)
        {
            byte[] StrRes = Encoding.Default.GetBytes(sourceStr);
            HashAlgorithm mySHA = new SHA1CryptoServiceProvider();
            StrRes = mySHA.ComputeHash(StrRes);
            StringBuilder EnText = new StringBuilder();
            foreach (byte Byte in StrRes)
            {
                EnText.AppendFormat("{0:x2}", Byte);
            }
            return EnText.ToString().ToUpper();
        }

        //MD5加密
        public static string md5Encrypt(string sourceStr)
        {
            MD5 myMD5 = new MD5CryptoServiceProvider();
            byte[] HashCode;
            HashCode = Encoding.Default.GetBytes(sourceStr);
            HashCode = myMD5.ComputeHash(HashCode);
            StringBuilder EnText = new StringBuilder();
            foreach (byte Byte in HashCode)
            {
                EnText.AppendFormat("{0:x2}", Byte);
            }
            return EnText.ToString().ToUpper();
        }

        //弹出提示对话框
        public static void alertBox(string message, Page thisPage)
        {
            thisPage.ClientScript.RegisterStartupScript(thisPage.GetType(), "", "<script>alert('" + message.Replace("'", "") + "');</script>");
        }
    }
}
